/*
 * Copyright (c) 2025 CAX Conversion Project
 */
package com.comac.ins.bomt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.bomt.common.enums.BizFileTypeEnum;
import com.comac.ins.bomt.common.enums.BomDetailTypeEnum;
import com.comac.ins.bomt.domain.*;
import com.comac.ins.bomt.domain.vo.*;
import com.comac.ins.bomt.mapper.*;
import com.comac.ins.bomt.service.BomQueryService;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.exception.BizException;
import com.comac.ins.common.core.utils.BizAssertUtil;
import com.comac.ins.common.json.utils.JsonUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author zhanghongyi
 * @date 2024/8/6 16:32
 * @description BomQueryService
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BomQueryServiceImpl implements BomQueryService {

    private final BomtBizFileMapper bomtBizFileMapper;

    private final BomtBomInfoMapper bomInfoMapper;

    private final BomtStandardBomDetailMapper standardBomDetailMapper;

    private final BomtStrengthBomDetailMapper strengthBomDetailMapper;

    private final BomtStrengthVsStandardChangeDetailMapper strengthVsStandardChangeDetailMapper;

    private final BomtStatusVsStrengthChangeDetailMapper statusVsStrengthChangeDetailMapper;

    private final BomtModelStatusDetailMapper modelStatusDetailMapper;

    @Override
    public TableDataInfo<BizFileVo> listOriginalByPage(LoginUser loginUser, String aircraftModel, PageQuery pageQuery) {
        Page<BizFileVo> page = bomtBizFileMapper.selectVoPage(pageQuery.build(), new LambdaQueryWrapper<BizFile>().eq(BizFile::getAircraftModel, aircraftModel));
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<String> listTrackByPage(LoginUser loginUser, String aircraftModel, BomDetailTypeEnum detailType, PageQuery pageQuery) {
        //创建对象
        QueryWrapper<BomInfo> wrapper = new QueryWrapper<>();
        wrapper.select("track", "max(update_time) as update_time");
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.groupBy("track");
        wrapper.orderByDesc("update_time");
        switch (detailType) {
            case SBOM:
                wrapper.isNotNull("standard_bom_file_id");
                break;
            case QBOM:
                wrapper.isNotNull("strength_bom_file_id");
                break;
            case QBOM_SBOM_CHANGE:
                wrapper.isNotNull("strength_vs_standard_file_id");
                break;
            case MSTS_QBOM_CHANGE:
                wrapper.isNotNull("status_vs_strength_file_id");
                break;
            default:
                throw new BizException("bom detail type not support");

        }
        Page<BomInfoVo> pageData = bomInfoMapper.selectVoPage(pageQuery.build(), wrapper);
        Page<String> page = new Page<>();
        BeanUtils.copyProperties(pageData, page);
        page.setRecords(pageData.getRecords().stream().map(BomInfoVo::getTrack).toList());
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<TrackInfoVo> listTrackInfoByPage(LoginUser loginUser, String aircraftModel, BomDetailTypeEnum detailType, PageQuery pageQuery){
        TableDataInfo<String> data = listTrackByPage(loginUser, aircraftModel, detailType, pageQuery);
        TableDataInfo<TrackInfoVo> result = new TableDataInfo<>();
        BeanUtils.copyProperties(data, result);
        result.setRows(getTrackInfos(aircraftModel, data.getRows()));
        return result;
    }

    @Override
    public TableDataInfo<BomInfoVo> listBomByPage(LoginUser loginUser, String aircraftModel, String batchNo, BomDetailTypeEnum detailType, PageQuery pageQuery) {
        //创建对象
        QueryWrapper<BomInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        if (StringUtils.isNotBlank(batchNo)) {
            wrapper.eq("track", batchNo);
        }
        switch (detailType) {
            case SBOM:
                wrapper.isNotNull("standard_bom_file_id");
                break;
            case QBOM:
                wrapper.isNotNull("strength_bom_file_id");
                break;
            case QBOM_SBOM_CHANGE:
                wrapper.isNotNull("strength_vs_standard_file_id");
                break;
            case MSTS_QBOM_CHANGE:
                wrapper.isNotNull("status_vs_strength_file_id");
                break;
            default:
                throw new BizException("bom detail type not support");
        }
        wrapper.orderByDesc("update_time");
        wrapper.orderByAsc("name");

        Page<BomInfoVo> page = bomInfoMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<DetailStandardBomVo> listStandardBomDetailByPage(LoginUser loginUser, String aircraftModel, String track, String groupType, DetailStandardBomVo query, PageQuery pageQuery) {
        //创建对象
        BomInfo bomInfo = getBomInfoByModelTrackAndGroupType(aircraftModel, track, groupType);
        BizAssertUtil.notNull(bomInfo.getStandardBomFileId(), "please generate before query");
        QueryWrapper<DetailStandardBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (StringUtils.isNotBlank(query.getCode())) {
            wrapper.eq("code", query.getCode());
        }
        if (StringUtils.isNotBlank(query.getLevel())) {
            wrapper.eq("level", query.getLevel());
        }
        if (StringUtils.isNotBlank(query.getVersion())) {
            wrapper.eq("version", query.getVersion());
        }
        if (StringUtils.isNotBlank(query.getSectionName())) {
            wrapper.like("section_name", query.getSectionName());
        }
        if (StringUtils.isNotBlank(query.getName())) {
            wrapper.like("name", query.getName());
        }
        wrapper.orderByAsc("ord");
        Page<DetailStandardBomVo> page = standardBomDetailMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<DetailStrengthBomVo> listStrengthCrossTrackDetailByPage(LoginUser loginUser, DetailStrengthBomVo query, PageQuery pageQuery) {
        //创建对象
        QueryWrapper<DetailStrengthBom> wrapper = new QueryWrapper<>();
        wrapper.select("distinct aircraft_model,group_type,substring(code,1,length(code)-1) as sub_group_type,name,level,code,version,version_num");
        wrapper.eq("aircraft_model", query.getAircraftModel());
        if (StringUtils.isNotBlank(query.getCode())) {
            wrapper.eq("code", query.getCode());
        }
        if (StringUtils.isNotBlank(query.getGroupType())) {
            wrapper.eq("group_type", query.getGroupType());
        }
        if (StringUtils.isNotBlank(query.getSubGroupType())) {
            wrapper.eq("substring(code,1,length(code)-1)", query.getSubGroupType());
        }
        if (StringUtils.isNotBlank(query.getName())) {
            wrapper.like("name", query.getName());
        }
        wrapper.orderByAsc(Arrays.asList("aircraft_model","group_type","code","version","version_num","name"));
        Page<DetailStrengthBomVo> page = strengthBomDetailMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<DetailStrengthBomVo> listStrengthBomDetailByPage(LoginUser loginUser, String aircraftModel, String track, String groupType, DetailStrengthBomVo query, PageQuery pageQuery) {
        BomInfo bomInfo = getBomInfoByModelTrackAndGroupType(aircraftModel, track, groupType);
        BizAssertUtil.notNull(bomInfo.getStrengthBomFileId(), "please generate before query");
        //创建对象
        QueryWrapper<DetailStrengthBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (StringUtils.isNotBlank(query.getCode())) {
            wrapper.eq("code", query.getCode());
        }
        if (StringUtils.isNotBlank(query.getLevel())) {
            wrapper.eq("level", query.getLevel());
        }
        if (StringUtils.isNotBlank(query.getVersion())) {
            wrapper.eq("version", query.getVersion());
        }
        if (StringUtils.isNotBlank(query.getName())) {
            wrapper.like("name", query.getName());
        }
        wrapper.orderByAsc("ord");
        Page<DetailStrengthBomVo> page = strengthBomDetailMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<DetailStrengthStandardChangeVo> listStrengthVsStandardChangeDetailByPage(LoginUser loginUser, String aircraftModel, String track, String groupType, DetailStrengthStandardChangeVo query, PageQuery pageQuery) {
        BomInfo bomInfo = getBomInfoByModelTrackAndGroupType(aircraftModel, track, groupType);
        BizAssertUtil.notNull(bomInfo.getStrengthVsStandardFileId(), "please generate before query");
        //创建对象
        QueryWrapper<DetailStrengthStandardChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (StringUtils.isNotBlank(query.getCode())) {
            wrapper.eq("code", query.getCode());
        }
        if (StringUtils.isNotBlank(query.getLevel())) {
            wrapper.eq("level", query.getLevel());
        }
        if (StringUtils.isNotBlank(query.getVersion())) {
            wrapper.eq("version", query.getVersion());
        }
        if (StringUtils.isNotBlank(query.getName())) {
            wrapper.like("name", query.getName());
        }
        if (StringUtils.isNotBlank(query.getChangeType())) {
            wrapper.eq("changeType", query.getChangeType());
        }
        wrapper.orderByAsc("ord");
        Page<DetailStrengthStandardChangeVo> page = strengthVsStandardChangeDetailMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<DetailStatusStrengthChangeVo> listStatusVsStrengthChangeDetailByPage(LoginUser loginUser, String aircraftModel, String track, String groupType, DetailStatusStrengthChangeVo query, PageQuery pageQuery) {
        BomInfo bomInfo = getBomInfoByModelTrackAndGroupType(aircraftModel, track, groupType);
        BizAssertUtil.notNull(bomInfo.getStatusVsStrengthSummary(), "please generate before query");
        //创建对象
        QueryWrapper<DetailStatusStrengthChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (StringUtils.isNotBlank(query.getCode())) {
            wrapper.eq("code", query.getCode());
        }
        if (StringUtils.isNotBlank(query.getLevel())) {
            wrapper.eq("level", query.getLevel());
        }
        if (StringUtils.isNotBlank(query.getVersion())) {
            wrapper.eq("version", query.getVersion());
        }
        if (StringUtils.isNotBlank(query.getName())) {
            wrapper.like("name", query.getName());
        }
        if (StringUtils.isNotBlank(query.getChangeType())) {
            wrapper.eq("changeType", query.getChangeType());
        }
        wrapper.orderByAsc("ord");
        Page<DetailStatusStrengthChangeVo> page = statusVsStrengthChangeDetailMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }


    @Override
    public List<DetailStandardBom> queryStandardBomDetailsByBomInfo(BomInfo bomInfo) {
        QueryWrapper<DetailStandardBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", bomInfo.getAircraftModel());
        wrapper.eq("track", bomInfo.getTrack());
        wrapper.eq("group_type", bomInfo.getGroupType());
        wrapper.orderByAsc("ord");
        List<DetailStandardBom> result = standardBomDetailMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(result, "standard detail not found");
        return result;
    }

    @Override
    public List<DetailStrengthBom> queryStrengthBomDetailsByBomInfo(BomInfo bomInfo) {
        QueryWrapper<DetailStrengthBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", bomInfo.getAircraftModel());
        wrapper.eq("track", bomInfo.getTrack());
        wrapper.eq("group_type", bomInfo.getGroupType());
        wrapper.orderByAsc("ord");
        List<DetailStrengthBom> result = strengthBomDetailMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(result, "strength detail not found");
        return result;
    }

    @Override
    public List<DetailModelStatus> queryModelStatusDetailsByBomInfo(BomInfo bomInfo) {
        QueryWrapper<DetailModelStatus> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", bomInfo.getAircraftModel());
        wrapper.eq("track", bomInfo.getTrack());
        wrapper.eq("group_type", bomInfo.getGroupType());
        wrapper.orderByAsc("ord");
        List<DetailModelStatus> result = modelStatusDetailMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(result, "model status detail not found");
        return result;
    }

    @Override
    public List<DetailStrengthStandardChange> queryStrengthStandardChangeDetailsByBomInfo(BomInfo bomInfo) {
        QueryWrapper<DetailStrengthStandardChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", bomInfo.getAircraftModel());
        wrapper.eq("track", bomInfo.getTrack());
        wrapper.eq("group_type", bomInfo.getGroupType());
        wrapper.orderByAsc("ord");
        List<DetailStrengthStandardChange> result = strengthVsStandardChangeDetailMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(result, "strength standard change detail not found");
        return result;
    }

    @Override
    public List<DetailStatusStrengthChange> queryStatusStrengthChangeDetailsByBomInfo(BomInfo bomInfo) {
        QueryWrapper<DetailStatusStrengthChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", bomInfo.getAircraftModel());
        wrapper.eq("track", bomInfo.getTrack());
        wrapper.eq("group_type", bomInfo.getGroupType());
        wrapper.orderByAsc("ord");
        List<DetailStatusStrengthChange> result = statusVsStrengthChangeDetailMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(result, "status strength change detail not found");
        return result;
    }

    @Override
    public BomInfo getBomInfoById(Long bomId) {
        BomInfo bomInfo = bomInfoMapper.selectById(bomId);
        BizAssertUtil.notNull(bomInfo, "bomInfo not found");
        return bomInfo;
    }

    @Override
    public List<BomInfo> getBomInfoByIds(List<Long> bomIdList) {
        List<BomInfo> bomInfos = bomInfoMapper.selectBatchIds(bomIdList);
        bomInfos.forEach(bomInfo -> BizAssertUtil.notNull(bomInfo, "bomInfo not found"));
        return bomInfos;
    }

    @Override
    public BomInfo getBomInfoByModelTrackAndGroupType(String aircraftModel, String track, String groupType) {
        QueryWrapper<BomInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("group_type", groupType);
        wrapper.eq("track", track);
        BomInfo bomInfo = bomInfoMapper.selectOne(wrapper);
        BizAssertUtil.notNull(bomInfo, "bomInfo not found");
        return bomInfo;
    }

    @Override
    public List<BomInfo> getBomInfoListByModelTrack(String aircraftModel, String track) {
        QueryWrapper<BomInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.orderByAsc("name");
        List<BomInfo> bomInfoList = bomInfoMapper.selectList(wrapper);
        BizAssertUtil.notEmpty(bomInfoList, "bomInfo not found");
        return bomInfoList;
    }

    private List<TrackInfoVo> getTrackInfos(String aircraftModel, List<String> tracks){
        List<TrackInfoVo> result  = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(tracks)) {
            QueryWrapper<BizFile> wrapper = new QueryWrapper<>();
            wrapper.eq("aircraft_model", aircraftModel);
            wrapper.in("track", tracks);
            wrapper.in("file_type", Arrays.asList(BizFileTypeEnum.INIT.getCode(), BizFileTypeEnum.OBOM.getCode()));
            List<BizFile> bizFileList = bomtBizFileMapper.selectList(wrapper);

            for (BizFile file : bizFileList) {
                TrackInfoVo trackInfo = new TrackInfoVo();
                trackInfo.setTrack(file.getTrack());
                result.add(trackInfo);
                try {
                    FileExtraInfo extra = JsonUtils.parseObject(file.getExtraInfo(), FileExtraInfo.class);
                    if (null != extra && extra.getBatchDesc() != null) {
                        trackInfo.setDesc(extra.getBatchDesc());
                    }
                } catch (Exception e) {
                    log.error("get biz file info fail", e);
                }
            }
        }
        return result;

    }
}
